package com.cbn.ibcp.web.jishiting.operator.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.cbn.ibcp.common.core.controller.BaseController;
import com.cbn.ibcp.common.core.domain.PageResult;
import com.cbn.ibcp.common.core.domain.Result;
import com.cbn.ibcp.common.core.page.TableDataInfo;
import com.cbn.ibcp.common.thread.ExecutorServiceUtil;
import com.cbn.ibcp.jishiting.gs.cms.domain.*;
import com.cbn.ibcp.jishiting.gs.cms.service.*;
import com.cbn.ibcp.jishiting.rms.bo.ResourceStreamBO;
import com.cbn.ibcp.jishiting.rms.bo.ResourceStreamOrgBO;
import com.cbn.ibcp.jishiting.rms.domain.*;
import com.cbn.ibcp.jishiting.rms.service.*;
import com.cbn.ibcp.web.common.config.GsCmsConfig;
import com.cbn.ibcp.web.init.LoadDatasource;
import com.cbn.ibcp.web.jishiting.operator.convert.ResourceStreamBOConvert;
import com.cbn.ibcp.web.jishiting.operator.convert.ResourceStreamDTOConvert;
import com.cbn.ibcp.web.jishiting.operator.convert.ResourceStreamOrgBOConvert;
import com.cbn.ibcp.web.jishiting.operator.convert.ResourceStreamOrgDTOConvert;
import com.cbn.ibcp.web.jishiting.operator.dto.ResourceStreamDTO;
import com.cbn.ibcp.web.jishiting.operator.dto.ResourceStreamOrgDTO;
import com.cbn.ibcp.web.jishiting.operator.vo.ResourceStreamOrgVO;
import com.cbn.ibcp.web.jishiting.operator.vo.ResourceStreamVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/resourceStream")
@RequiredArgsConstructor
public class ResourceStreamController extends BaseController {


    private final IResourceStreamService resourceStreamService;


    private final IResourceStreamOrgService resourceStreamOrgService;


    private final IResBaseService resBaseService;

    private final IResVideoEpisodeService resVideoEpisodeService;


    private final IResCpService resCpService;


    private final IResBasePlayConfigService resBasePlayConfigService;

    private final ICpVideoService cpVideoService;

    private final IOrgService orgService;

    private final INodeService nodeService;

    private final INodeVideoService nodeVideoService;

    private final ICpService cpService;

    @PreAuthorize("@ss.hasPermi('jishiting:rms:resourcestream:list')")
    @GetMapping("/selectWithEpisodeListPage")
    public PageResult<ResourceStreamVO> selectWithEpisodeListPage(ResourceStreamDTO resourceStreamDTO) {
        ResourceStreamBO resourceStreamBO = ResourceStreamDTOConvert.convertTOResourceStreamBO(resourceStreamDTO);
        startPage();
        List<ResourceStreamBO> resourceStreamBOList = resourceStreamService.selectWithEpisodeList(resourceStreamBO);
        TableDataInfo dataTable = getDataTable(resourceStreamBOList);
        if (CollectionUtil.isEmpty(resourceStreamBOList)) {
            return PageResult.ok(dataTable.getTotal(), null);
        }
        List<ResourceStreamVO> resourceStreamVOList = resourceStreamBOList.stream().map(ResourceStreamBOConvert::convertToResourceStreamVO).collect(Collectors.toList());
        List<Long> videoIds = resourceStreamBOList.stream().map(ResourceStreamBO::getEpisodeId).collect(Collectors.toList());
        List<CpVideo> cpVideoList = cpVideoService.getListByVideoIdList(videoIds);
        Map<String, CpVideo> cpVideoMap = cpVideoList.stream().collect(Collectors.toMap(CpVideo::getVideoId, cpVideo -> cpVideo));
        if (MapUtil.isEmpty(cpVideoMap)) {
            cpVideoMap = new HashMap<>();
        }
        List<Cp> cps = cpService.selectList();
        Map<Long, Cp> cpMap = cps.stream().collect(Collectors.toMap(Cp::getId, cp -> cp, (v1, v2) -> v1));
        Map<String, CpVideo> finalCpVideoMap = cpVideoMap;
        resourceStreamVOList.forEach(resourceStreamVO -> {
            CpVideo cpVideo = finalCpVideoMap.get(resourceStreamVO.getEpisodeId());
            if (cpVideo != null) {
                resourceStreamVO.setAlbumId(cpVideo.getAlbumId());
                resourceStreamVO.setOssUrl(cpVideo.getOssUrl());
                resourceStreamVO.setSourceTsUrl(cpVideo.getSourceTsUrl());
                resourceStreamVO.setOssTsUrl(cpVideo.getOssTsUrl());
                resourceStreamVO.setSourceInOss(cpVideo.getSourceInOss());
                resourceStreamVO.setOssInjectStatus(cpVideo.getOssInjectStatus());
                Cp cp = cpMap.get(cpVideo.getCpIdx());
                if (cp != null) {
                    resourceStreamVO.setCdnCpCode(cp.getCpCode());
                }
            }
            //如果是电影
            if (resourceStreamVO.getResType() == 1) {
                resourceStreamVO.setAlbumName(resourceStreamVO.getEpisodeName());
                resourceStreamVO.setAlbumStatus(resourceStreamVO.getEpisodeStatus());
                resourceStreamVO.setAlbumCpStatus(resourceStreamVO.getEpisodeCpStatus());
            }
        });
        return PageResult.ok(dataTable.getTotal(), resourceStreamVOList);
    }


    @PreAuthorize("@ss.hasPermi('jishiting:rms:resourcestream:origin:province:list')")
    @GetMapping("/selectProvinceListWithParam")
    public Result<List<ResourceStreamOrgVO>> selectProvinceListWithParam(String videoId, Integer quality, @RequestParam(value = "orgCodes", required = false) List<String> orgCodes) {
        if (videoId == null) {
            return Result.fail("参数错误");
        }
        Long videoIdLong = Long.parseLong(videoId);
        //查询注入省份
        List<ResBase> resBaseList = resBaseService.getListByIdListAndResTypeList(ListUtil.toList(videoIdLong), ListUtil.toList(1, 21));
        if (CollectionUtil.isEmpty(resBaseList)) {
            return Result.ok(ListUtil.empty());
        }
        ResBase resBase = resBaseList.get(0);
        Long contentProviderId = resBase.getContentProviderId();
        ResCp resCp = resCpService.getById(contentProviderId);
        String code = resCp.getCode();
        ResVideoEpisode resVideoEpisode = resVideoEpisodeService.selectById(videoIdLong);
        List<ResBasePlayConfig> resBasePlayConfigList = resBasePlayConfigService.getListByCpCode(code);
        if (CollectionUtil.isEmpty(resBasePlayConfigList)) {
            return Result.ok(ListUtil.empty());
        }
        List<String> orgCodeList = resBasePlayConfigList.stream().map(ResBasePlayConfig::getOrgCode).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(orgCodeList)) {
            return Result.ok(ListUtil.empty());
        }
        if (CollectionUtil.isNotEmpty(orgCodes)) {
            orgCodeList.retainAll(orgCodes);
        }
        //过滤掉不能注入的orgCode
        List<String> cdnOrgCodeList = GsCmsConfig.cdnOrgCodeList;
        orgCodeList.removeIf(orgCode -> !cdnOrgCodeList.contains(orgCode));
        ResourceStream originResourceStream = resourceStreamService.selectByResIdAndQuality(null, resBase.getId(), quality);
        if (originResourceStream == null) {
            return Result.ok(ListUtil.empty());
        }
        List<Callable<ResourceStreamOrgVO>> callableList = new ArrayList<>();
        for (String orgCode : orgCodeList) {
            callableList.add(() -> getProvinceResourceStreamOrgVOList(orgCode, resBase, resVideoEpisode, originResourceStream));
        }
        List<ResourceStreamOrgVO> resourceStreamOrgVOList = ExecutorServiceUtil.execute(ExecutorServiceUtil.orgCodeSelectExecutorService, callableList);
        return Result.ok(resourceStreamOrgVOList);
    }


    /**
     * 获取分省资源流
     *
     * @param orgCode
     * @param originResourceStream
     * @return
     */
    private ResourceStreamOrgVO getProvinceResourceStreamOrgVOList(String orgCode, ResBase resBase, ResVideoEpisode resVideoEpisode, ResourceStream originResourceStream) {
        if (LoadDatasource.notInjectOrgCodeList.contains(orgCode)) {
            return null;
        }
        Integer quality = originResourceStream.getQuality();
        ResourceStream resourceStream = null;
        ResourceStreamOrg resourceStreamOrg = null;
        ResBase albumResBase = null;
        ResBase provinceResBase = null;
        NodeVideo nodeVideo = null;
        try {
            log.info("selectProvinceListWithParam,selectOneByResId and selectListByStreamId  orgCode:{}", orgCode);
            resourceStream = resourceStreamService.selectByResIdAndQuality(orgCode, resBase.getId(), quality);
            if (resourceStream == null || resourceStream.getId() == null) {
                return null;
            }
            resourceStreamOrg = resourceStreamOrgService.selectListByStreamId(orgCode, orgCode, resourceStream.getId());
            provinceResBase = resBaseService.getOneByIdAndResType(orgCode, orgCode, resVideoEpisode.getId(), resBase.getResType());
            albumResBase = resBaseService.getOneAlbumById(orgCode, orgCode, resVideoEpisode.getAlbumId());
            CpVideo cpVideo = cpVideoService.getByVideoId(StrUtil.toStringOrNull(resBase.getId()));
            if (Objects.isNull(cpVideo)) {
                return null;
            }
            Org org = orgService.selectByOrgCode(orgCode);
            if (Objects.isNull(org)) {
                return null;
            }
            Node node = nodeService.selectByOrgId(org.getId());
            if (Objects.nonNull(node)) {
                nodeVideo = nodeVideoService.getByAssetId(cpVideo.getAssetId(), node.getId());
            }
        } catch (Exception e) {
            log.error("查询播放配置出错", e);
        }
        //封装VO数据
        ResourceStreamOrgVO resourceStreamOrgVO = new ResourceStreamOrgVO();
        resourceStreamOrgVO.setOrgCode(orgCode);
        resourceStreamOrgVO.setAlbumId(StrUtil.toStringOrNull(resVideoEpisode.getAlbumId()));
        resourceStreamOrgVO.setResType(resBase.getResType());
        resourceStreamOrgVO.setEpisodeId(StrUtil.toStringOrNull(originResourceStream.getResId()));
        resourceStreamOrgVO.setEpisodeName(resBase.getDisplayName());
        if (resourceStream != null) {
            resourceStreamOrgVO.setQuality(resourceStream.getQuality());
            resourceStreamOrgVO.setResourceStreamInjectStatus(resourceStream.getInjectStatus());
        }
        if (resourceStreamOrg != null) {
            resourceStreamOrgVO.setId(StrUtil.toStringOrNull(resourceStreamOrg.getId()));
            resourceStreamOrgVO.setResourceStreamOrgInjectStatus(resourceStreamOrg.getInjectStatus());
            resourceStreamOrgVO.setCreateTime(DateUtil.format(resourceStreamOrg.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
            resourceStreamOrgVO.setUpdateTime(DateUtil.format(resourceStreamOrg.getUpdateTime(), DatePattern.NORM_DATETIME_PATTERN));
        }
        if (albumResBase != null) {
            resourceStreamOrgVO.setAlbumId(StrUtil.toStringOrNull(albumResBase.getId()));
            resourceStreamOrgVO.setAlbumName(albumResBase.getDisplayName());
            resourceStreamOrgVO.setAlbumCpStatus(albumResBase.getCpStatus());
            resourceStreamOrgVO.setAlbumStatus(albumResBase.getStatus());
        }
        if (provinceResBase != null) {
            resourceStreamOrgVO.setEpisodeStatus(provinceResBase.getStatus());
            resourceStreamOrgVO.setEpisodeCpStatus(provinceResBase.getCpStatus());
            resourceStreamOrgVO.setEpisodeInjectStatus(provinceResBase.getInjectStatus());
        }
        if (nodeVideo != null) {
            resourceStreamOrgVO.setNodeInjectStatus(nodeVideo.getInjectStatus());
        }
        return resourceStreamOrgVO;
    }

    @PreAuthorize("@ss.hasPermi('jishiting:rms:resourcestreamorg:list')")
    @GetMapping("/selectProvinceWithEpisodeListPage")
    public PageResult<ResourceStreamOrgVO> selectProvinceWithEpisodeListPage(ResourceStreamOrgDTO resourceStreamOrgDTO) {
        if (resourceStreamOrgDTO == null) {
            resourceStreamOrgDTO = new ResourceStreamOrgDTO();
        }
        String orgCode = resourceStreamOrgDTO.getOrgCode();
        if (StrUtil.isBlank(orgCode)) {
            return PageResult.fail("请选择省网");
        }
        ResourceStreamOrgBO resourceStreamOrgBO = ResourceStreamOrgDTOConvert.convertTOResourceStreamBO(resourceStreamOrgDTO);
        startPage();
        List<ResourceStreamOrgBO> resourceStreamOrgBOList = resourceStreamOrgService.selectListByBO(resourceStreamOrgDTO.getOrgCode(), resourceStreamOrgBO);
        TableDataInfo dataTable = getDataTable(resourceStreamOrgBOList);
        if (CollectionUtil.isEmpty(resourceStreamOrgBOList)) {
            return PageResult.ok(dataTable.getTotal(), null);
        }
        List<ResourceStreamOrgVO> resourceStreamOrgVOList = resourceStreamOrgBOList.stream().map(ResourceStreamOrgBOConvert::convertToResourceStreamOrgVO).collect(Collectors.toList());
        List<Long> videoIdList = resourceStreamOrgBOList.stream().map(ResourceStreamOrgBO::getEpisodeId).collect(Collectors.toList());
        Map<String, CpVideo> cpVideoMap = null;
        List<CpVideo> listByVideoIdList = cpVideoService.getListByVideoIdList(videoIdList);
        if (CollectionUtil.isNotEmpty(listByVideoIdList)) {
            cpVideoMap = listByVideoIdList.stream().collect(Collectors.toMap(CpVideo::getVideoId, cpVideo -> cpVideo, (v1, v2) -> v1));
        } else {
            cpVideoMap = new HashMap<>();
        }
        Org org = orgService.selectByOrgCode(orgCode);
        Node node = nodeService.selectByOrgId(org.getId());
        List<NodeVideo> nodeVideoList = null;
        if (Objects.nonNull(node) || CollUtil.isEmpty(videoIdList)) {
            nodeVideoList = nodeVideoService.getListByVideoIdList(videoIdList, node.getId());
        }
        Map<String, NodeVideo> nodeVideoMap = null;
        if (CollectionUtil.isNotEmpty(nodeVideoList)) {
            nodeVideoMap = nodeVideoList.stream().collect(Collectors.toMap(NodeVideo::getVideoId, nodeVideo -> nodeVideo, (v1, v2) -> v1));
        } else {
            nodeVideoMap = new HashMap<>();
        }
        //获取全部的cp信息
        List<Cp> cps = cpService.selectList();
        Map<Long, Cp> cpMap = cps.stream().collect(Collectors.toMap(Cp::getId, cp -> cp, (v1, v2) -> v1));
        Map<String, CpVideo> finalCpVideoMap = cpVideoMap;
        Map<String, NodeVideo> finalNodeVideoMap = nodeVideoMap;
        resourceStreamOrgVOList.forEach(resourceStreamOrgVO -> {
            CpVideo cpVideo = finalCpVideoMap.get(resourceStreamOrgVO.getEpisodeId());
            if (Objects.nonNull(cpVideo)) {
                resourceStreamOrgVO.setOriginInjectStatus(cpVideo.getOssInjectStatus());
            }
            NodeVideo nodeVideo = finalNodeVideoMap.get(resourceStreamOrgVO.getEpisodeId());
            if (Objects.nonNull(nodeVideo)) {
                Cp cp = cpMap.get(nodeVideo.getCpIdx());
                if (Objects.nonNull(cp)) {
                    resourceStreamOrgVO.setNodeCpCode(cp.getCpCode());
                }
                resourceStreamOrgVO.setNodeInjectStatus(nodeVideo.getInjectStatus());
            }
            if (resourceStreamOrgVO.getResType() == 1) {
                resourceStreamOrgVO.setAlbumName(resourceStreamOrgVO.getEpisodeName());
                resourceStreamOrgVO.setAlbumStatus(resourceStreamOrgVO.getEpisodeStatus());
                resourceStreamOrgVO.setAlbumCpStatus(resourceStreamOrgVO.getEpisodeCpStatus());
            }
        });
        return PageResult.ok(dataTable.getTotal(), resourceStreamOrgVOList);
    }

}
